//
//  AppController.m
//  MusicAnalyzer
//
//  Created by jiro on 12/03/24.
//  Copyright 2012 jiro music. All rights reserved.
//

#import "AppController.h"

#import <queue>
#import <map>

#import "../Common/MidiSystem.h"
#import "CommandExecutionSystem.h"

StateMachine* SM = [ StateMachine sharedStateMachine ];				//	for short hand
CommandExecuter* CE = [ CommandExecuter sharedCommandExecuter ];	//	for short hand

/**	@brief midi device notification */
void MidiDeviceNotify( void* selfPtr, std::queue< const sc::MidiMessage* > messages )
{
	while ( not messages.empty() )
	{
		NSLog( @"%s", messages.front()->ToString().c_str() );
		messages.pop();
	}
}

@implementation AppController

@synthesize musicSheetView;
@synthesize graphView;
@synthesize chordTableView;

- (id) initWithWindowNibName:(NSString *)windowNibName
{
	self = [ super initWithWindowNibName: windowNibName ];

	//	---- initialize state machine & command executer ---- //
	SM = [ StateMachine sharedStateMachine ];
	CE = [ CommandExecuter sharedCommandExecuter ];
	[ CE setAppController: self ];
	[ SM setAppController: self ];
	//	---------------------------------- //

	//	initilize other members
	deviceSetupWindowController = nil;
//	[ chordTableView fType: NSFocusRingOnly ];

	return self;
}

- (void) windowDidLoad
{
	// initialize command execute
	AppMouseEvent* e = [ [ AppMouseEvent alloc ] initWithInstance: musicSheetView ];
	Command* command = [ SM inputMouseEvent: e ];
	[ SM pushState: [ NeutralState sharedState ] ];
	[ CE executeCommand: command ];
}

- (IBAction) openDeviceSetupWindow: (id) sender
{
//	NSLog( @"- (IBAction) openDeviceSetupWindow: (id) sender" );

	if ( deviceSetupWindowController == nil )
	{
		deviceSetupWindowController = [ [  DeviceSetupWindowController alloc ] initWithWindowNibName: @"DeviceSetupWindow" ];
	}
	[ deviceSetupWindowController setAppController: self ];
	[ deviceSetupWindowController showWindow: self ];
}

- (void) setMidiInterface: ( sc::MidiInterface0* ) midiInterfaceArg
{
	midiInterface = midiInterfaceArg;
	midiInterface->AddObserver( self, & MidiDeviceNotify );
}

- (void) setDeviceInfos: ( std::vector< sc::DeviceInfo* >* ) infos
{
	[ [ self document ] setDeviceInfos: infos ];
}

- (void) mouseDown:(NSEvent *)theEvent
{
//	NSLog( @"AppController: - (void) mouseDown:(NSEvent *)theEvent" );
	if ( not [ theEvent isKindOfClass: [ AppEvent class ] ] )
	{
		[ super mouseDown: theEvent ]; 
		return;
	}

	AppMouseEvent* e = (AppMouseEvent*) theEvent;
	Command* command = [ SM inputMouseEvent: e ];
	if ( command == nil )
	{
		return;
	}

	[ CE executeCommand: command ];
	if ( [ command undoable ] )
	{
		executedCommandStack.push( command );
	}
}

@end
